package com.zoe.onelink.mybatis.interceptor.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.zoe.onelink.annotation.mybatis.SpellField;
import com.zoe.onelink.common.entity.IBaseEntity;
import com.zoe.onelink.mybatis.interceptor.MybatisEntityUpdateInterceptor;
import com.zoe.onelink.mybatis.properties.OnelinkMybatisPluginProperties;
import com.zoe.onelink.util.CodeUtil;
import lombok.RequiredArgsConstructor;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2021</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2021-03-22
 */
@RequiredArgsConstructor
public class MybatisSpellFieldUpdateInterceptor implements MybatisEntityUpdateInterceptor {

    /**
     * key = className , value = spellFieldName
     */
    private final Map<Class<? extends IBaseEntity>, String> spellFieldCache = new ConcurrentHashMap<>(8);
    private final OnelinkMybatisPluginProperties onelinkMybatisProperties;


    /**
     * 设置拼音码和五笔码
     *
     * @param entity 实体
     */
    @Override
    public void onUpdate(IBaseEntity entity) {
        Class<? extends IBaseEntity> clazz = entity.getClass();
        String spellFieldName = this.spellFieldCache.computeIfAbsent(clazz, clazzName -> {
            Field[] fields = ReflectUtil.getFields(clazz);
            for (Field field : fields) {
                if (field.getDeclaredAnnotation(SpellField.class) != null) {
                    field.setAccessible(true);
                    return field.getName();
                }
            }
            return "";
        });
        // 如果实体类不包含@SpellField注解,直接返回
        if (StrUtil.isBlank(spellFieldName)) {
            return;
        }
        String fieldValue = Optional.ofNullable(BeanUtil.getFieldValue(entity, spellFieldName)).orElse("").toString();
        // 如果@SpellField注解标记的字段值为空,直接返回
        if (StrUtil.isBlank(fieldValue)) {
            return;
        }
        String pinyinCode = CodeUtil.cn2FirstSpell(fieldValue);
        BeanUtil.setFieldValue(entity, this.onelinkMybatisProperties.getMetaField().getSpellFieldName(), StrUtil.blankToDefault(pinyinCode, ""));
        String wbCode = CodeUtil.getWBCode(fieldValue);
        BeanUtil.setFieldValue(entity, this.onelinkMybatisProperties.getMetaField().getWbCodeFieldName(), StrUtil.blankToDefault(wbCode, ""));
    }

}
